rust 字符串的操作 -11

目录

一,前言

(一)Rust将字符串分类

(二)Rust将字符串 &str和String区别

二,五种声明方式

三,迭代器

四 ,追加字符串

五,删除

六,转换 &str  < - > String

七,替换,查找,批量修改等


 

 

一,前言


       不管在什么语言中,对字符串的处理都是必须且重要的,rust中的字符串数据类型关键字是String。

(一)Rust将字符串分类


             Rust将字符串分为两种: 
                                                     1) &str :固定长度字符串(也称字符串字面量
                                                     2) String :可以随意改变其长度。

 

(二)Rust将字符串 &strString区别


                &str字符串类型存储于栈上,str字符串序列存储于程序的静态只读数据段或者堆内存中。由两部分组成:
                        1) 指向字符串序列的指针;
                        2) 记录长度的值。

                 String类型本质是一个成员变量为Vec<u8>类型的结构体,所以它是直接将字符内容存放于堆中的。由三部分组成:
                       1) 执行堆中字节序列的指针(as_ptr方法)
                       2) 记录堆中字节序列的字节长度(len方法)
                       3) 堆分配的容量(capacity方法)

 

二,五种声明方式

fn  main(){

     //1.第一种方式:通过String的new创建一个空的字符串
    let mut my_str = String::new();//不能有字符变量
    my_str.push_str("my_str"); //为这个空的字符串变量使用push_str方法添加一个值

    //2.第二种方式 通过String的from创建一个字符串
    let mut my_str2 = String::from("my_str");
    my_str2.push_str("2");

    //3.第三种方式,直接书写字符串字面量
    let mut my_str3 = "my_str3"; // &str

    //4.第四种方式  通过to_string把字面量变成一个字符串
    let mut my_str4 = "my_str".to_string();
    my_str4.push_str("4");

    //5.第五种方式  通过with_capacity创建一个带有预先分配的初始缓冲区的空字符串
    //如果已知String的最终大小,String::with_capacity则应首选。
    let mut my_str5 = String::with_capacity(7);
    my_str5.push_str("my_str5");

    println!("{} , {} , {} , {} , {}" , my_str , my_str2 , my_str3 , my_str4 , my_str5);

}

console:

my_str , my_str2 , my_str3 , my_str4 , my_str5

 

三,迭代器

          Rust中的字符串不能使用索引访问其中的字符,可以通过bytes和chars两个方法来分别返回按字节和按字符迭代的迭代器


fn iter_f(){
    let mut my_str = String::from("my_str");
    let mut bytes = my_str.bytes();
    let mut chars = my_str.chars();
    println!("{:?} , {:?}", bytes , chars);
    for c in my_str.bytes() {
        println!("{}", c);
    }
    for c in my_str.chars() {
        println!("{}", c);
    }
    //从字符串中取单个字符
    let a = my_str.chars().nth(2);//nth 函数是从迭代器中取出某值的方法,请不要在遍历中这样使用!因为 UTF-8 每个字符的长度不一定相等!
    println!("{:?}", a);
}

console:

Bytes(Copied { it: Iter([109, 121, 95, 115, 116, 114]) }) , Chars(['m', 'y', '_', 's', 't', 'r'])
109
121
95
115
116
114
m
y
_
s
t
r
Some('_')

 

四 ,追加字符串

           五种追加字符串: insert,insert_str ,push和push_str,以及迭代器

fn push_f(){
    let mut my_str = String::new();
    my_str.push_str("my_str");//只能跟字面变量 &str

    let mut my_str2 = String::new();
    my_str2.push('2');//char

    let mut my_str3 = String::from(['3'][0]);//&str ,char(元素类型是这两个就行)

    let mut my_str4 = [4][0].to_string();//char ,i32,...

    // Ø 连接字符串:String实现了Add<&str>和AddAssign<&str>两个trait,所以可以使用“+”和“+=”来连接字符串
    my_str += &my_str2 ;//加&的意思是传入字符串对象的引用,但不释放所有权,为了可以使用使用原来的字符串变量
    my_str = my_str +  &my_str3;// 两个引用,只能一个引用一个具体对象
//    my_str3 = my_str +  &my_str3;//值会不能拼接到引用的对象上

    //不引用的对象失去所有权,my_str变成了空的字符串变量  borrow of moved value: `my_str`
    let mut my_str5 = my_str + &my_str4;
    my_str =  "my_str".to_string();//依然是String类型,只能赋值String类型

    println!("{} , {} , {} , {} , {}" , my_str , my_str2 , my_str3 , my_str4 , my_str5);

   

}

///迭代器chars追加
fn chars_f(){
    //1,把my_str6追加到my_str_7后
    let mut my_str6 = String::from("my_str");
    let mut my_str_7 = String::from("new");
    for c in my_str6.chars() {
        my_str_7.push(c);
    }
    
    //2,把my_str8补齐8位
    let mut my_str8 = String::from("0000");
    let len = my_str8.len();
    for _ in 0..8-len {
       my_str8.push('0');
    }
    println!("my_str_7:{} , my_str8:{}", my_str_7 , my_str8);
}


/// 插入字符串:insert和insert_str ,在某个下标之前插入
fn insert_f(){
    //可以在末尾追加也可以0 - String.len() 之间任何位置插入字符串
    let mut my_str = String::from("my_str");
    my_str.insert(my_str.len(),'1');//`char` 字符对象下标从0开始
    my_str.insert_str(my_str.len(),"2");//`&str`
    println!("{} " , my_str );//my_str12
}

fn main(){
   push_f();
   chars_f();
   insert_f();
}


console:

my_str , 2 , 3 , 4 , my_str234
my_str_7:newmy_str , my_str8:00000000
my_str12

 

五,删除

         五种删除字符串:remove、pop、truncate、clear和drain


fn del_f(){
    let mut my_str = String::from("my_str");

    //usize 删除参数对应下标的字符
//    my_str.remove(0);//y_str

    //从末尾删除字符
//    my_str.pop();//my_st

    //删除参数对应下标之后的字符
//    my_str.truncate(2);//my_

    //清空
//    my_str.clear();//有一个空所有权的空对象,这个比较有意思

    //删除固定范围内的字符串
    let n1 =0;let n2=3;
    my_str.drain(n1..n2);//  0..3
    println!("{}" , my_str );
}

 

六,转换 &str  < - > String

    把String转换为&str的代价很小,不过从&str转换到String涉及到分配内存。除非必要,没有理由这样做!

//&str  --> String
let s1 = "Hello".to_string();

let mut my_str = String::new();
my_str.push_str("my_str"); 


//String --> &str  
let s2:&str = &s1;

let string1 = String::from("abcd");
let result:&str = string1.as_str();

七,替换,查找,批量修改等

只列出部分常用的,如有需求 请看API:  https://doc.rust-lang.org/std/primitive.str.html#method.trim

    println!("{} ", "".starts_with("a"));
    println!("以什么开始 :{} {}",String::from("abc").starts_with("a"), "".starts_with("a"));
    println!("以什么结尾 :{} {}",String::from("abc").ends_with("c")  , "abc".ends_with("c"));//ends_with<'a, P>(&'a self, pat: P) -> bool
    let four: i32 = "4".parse().unwrap();
    println!("{} ", four+1);
    println!("{} {}", "a".repeat(4) ,String::from("b").repeat(4));//repeat(&self, n: usize) -> String
    println!("{} {}",  "".is_empty(),String::from("").is_empty());
    println!("{} {}", "this is old".replace("old", "new"),String::from("this is old").replace("old", "new"));
    let s = "foo foo 123 foo";
    println!("{} ", s.replace("foo", "1"));//全部替换
    println!("{} ", s.replacen("foo", "1" , 1));//替换几个
    let v: Vec<&str> = "1,2,3,4".split(',').collect();//"" == [""]
    println!("{:?} ", v);
    println!("{} {}  {}", " S S ".trim()," S S ".len(), " S S ".trim().len());//去掉的是两边的空格
    let s:String = "Hello, world!".chars()
        .map(|x| match x {
            '!' => '?',
            'A'...'Z' => 'X',
            'a'...'z' => 'x',
            _ => x}
        ).collect();
    println!("{}", s);

console:

    aaaa bbbb
    true true
    this is new this is new
    1 1 123 1 
    1 foo 123 foo 
    ["1", "2", "3", "4"] 
    S S 5  3
    Xxxxx, xxxxx?

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值